package shopcart

import (
	"context"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net/http"
	"shop_webs/order_web/api"
	"shop_webs/order_web/forms"
	"shop_webs/order_web/global"
	"shop_webs/order_web/proto"
	"strconv"
)

func List(ctx *gin.Context) {
	//获取购物车商品
	userId := ctx.GetInt("userId")
	zap.S().Infoln("当前用户是", userId)
	rsp, err := global.OrderClient.CartItemList(context.Background(), &proto.UserInfo{
		Id: int32(userId),
	})
	if err != nil {
		zap.S().Errorw("[List] 查询 【购物车列表】失败", "msg", err.Error())
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	if rsp.Total == 0 {
		ctx.JSON(http.StatusOK, gin.H{
			"total": 0,
		})
		return
	}

	var goodIds []int32
	cartItemMap := make(map[int32]proto.CartItemResponse)
	for _, cartItemResponse := range rsp.Data {
		goodIds = append(goodIds, cartItemResponse.GoodsId)
		cartItemMap[cartItemResponse.GoodsId] = *cartItemResponse
	}

	//请求商品服务获取商品信息
	goodsRsp, err := global.GoodsClient.BatchGetGoods(context.Background(), &proto.BatchGoodsIdInfo{
		Id: goodIds,
	})
	if err != nil {
		zap.S().Errorw("[List] 批量查询 【商品列表】失败", "msg", err.Error())
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	/*		前端格式
			{
				"total":12,
				"data":[
					{
						"id":1,
						"goods_id":421,
						"goods_name":421,
						"goods_price":421,
						"goods_image":421,
						"nums":421,
						"checked":421,
					}
				]
			}
	*/
	var goodList []map[string]interface{}
	for _, good := range goodsRsp.Data {
		cartItemResponse, _ := cartItemMap[good.Id]
		goodList = append(goodList, map[string]interface{}{
			"id":         cartItemResponse.Id,
			"goods_id":   cartItemResponse.GoodsId,
			"good_name":  good.Name,
			"good_image": good.GoodsFrontImage,
			"good_price": good.ShopPrice,
			"nums":       cartItemResponse.Nums,
			"checked":    cartItemResponse.Checked,
		})
	}

	ctx.JSON(http.StatusOK, gin.H{
		"total": goodsRsp.Total,
		"data":  goodList,
	})
}
func New(ctx *gin.Context) {
	//添加商品到购物车
	itemForm := forms.ShopCartItemForm{}
	if err := ctx.ShouldBind(&itemForm); err != nil {
		api.HandleValidatorError(err, ctx)
		return
	}

	//为了严谨性，添加商品到购物车之前，记得检查一下商品是否存在
	_, err := global.GoodsClient.GetGoodsDetail(context.Background(), &proto.GoodInfoRequest{
		Id: itemForm.GoodsId,
	})
	if err != nil {
		zap.S().Errorw("[List] 查询 【商品信息】失败", "msg", err.Error())
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}

	//如果现在添加到购物车的数量和库存的数量不一致
	invRsp, err := global.InventoryClient.InvDetail(context.Background(), &proto.GoodsInvInfo{
		GoodsId: itemForm.GoodsId,
	})
	if err != nil {
		zap.S().Errorw("[List] 查询 【库存信息】失败", "msg", err.Error())
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	if invRsp.Num < itemForm.Nums {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"nums": "库存不足",
		})
		return
	}

	userId := ctx.GetInt("userId")
	rsp, err := global.OrderClient.CreateCartItem(context.Background(), &proto.CartItemRequest{
		GoodsId: itemForm.GoodsId,
		UserId:  int32(userId),
		Num:     itemForm.Nums,
	})
	if err != nil {
		zap.S().Errorw("添加到购物车失败")
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"id": rsp.Id,
	})
	return
}
func Update(ctx *gin.Context) {
	//  o/v1/421
	id := ctx.Param("id")
	i, err := strconv.ParseInt(id, 10, 32) //???商品id???
	if err != nil {
		ctx.Status(http.StatusNotFound)
		return
	}

	shopCartItemUpdateForm := forms.ShopCartItemUpdateForm{}
	if err := ctx.ShouldBind(&shopCartItemUpdateForm); err != nil {
		api.HandleValidatorError(err, ctx)
		return
	}

	cartItemRequest := proto.CartItemRequest{
		GoodsId: int32(i),
		UserId:  int32(ctx.GetInt("userId")),
		Num:     shopCartItemUpdateForm.Nums,
	}
	if shopCartItemUpdateForm.Checked != nil {
		cartItemRequest.Checked = *shopCartItemUpdateForm.Checked
	}

	_, err = global.OrderClient.UpdateCartItem(context.Background(), &cartItemRequest)
	if err != nil {
		zap.S().Errorw("更新购物车记录失败")
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.Status(http.StatusOK)
}
func Delete(ctx *gin.Context) {
	//	o/v1/421
	id := ctx.Param("id")
	i, err := strconv.ParseInt(id, 10, 32) //???商品id???
	if err != nil {
		ctx.Status(http.StatusNotFound)
		return
	}

	_, err = global.OrderClient.DeleteCartItem(context.Background(), &proto.CartItemRequest{
		UserId:  int32(ctx.GetInt("userId")), //防止删除别人
		GoodsId: int32(i),
	})
	if err != nil {
		zap.S().Errorw("删除购物车记录失败")
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.Status(http.StatusOK)
}
